package com.share.example.selenium.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.share.common.common.Page;
import com.share.common.utils.GroovyUtil;
import com.share.common.exceptions.SysConfException;
import com.share.example.selenium.mapper.BaseConfMapper;
import com.share.example.selenium.model.amazon.seller.Goods;
import com.share.example.selenium.model.db.BaseConf;
import com.share.example.selenium.model.vo.BaseConfPageReq;
import com.share.example.selenium.service.IBaseConfService;
import groovy.lang.GroovyObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.WebDriver;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-10-15
 */
@Slf4j
@Service
public class BaseConfServiceImpl extends ServiceImpl<BaseConfMapper, BaseConf> implements IBaseConfService {
    final String SELECT_GOODS_G_CODE = "select_goods";
    final String SELECT_GOODS_DEFAULT = SELECT_GOODS_G_CODE + "_default";
    final String DIGNDING_TOKEN_SECRET = "dignding_token_secret";
    final String GOODS_ASIN = "asin";
    final String SYSTEM_CODE = System.getenv("SYSTEM_CODE");
    private Map<String, BaseConf> dictMap = new HashMap<>();
    private Map<String, GroovyObject> groovyMap = new HashMap<>();
    private Map<String, Goods> goodsMap = new HashMap<>();

    @Resource
    private BaseConfMapper baseConfMapper;

    @Override
    public Object init() {
        QueryWrapper<BaseConf> query = new QueryWrapper<>();
        query.eq("status", 1);
        List<BaseConf> list = baseConfMapper.selectList(null);
        Map<String, BaseConf> tmpMap = new HashMap<>();
        Map<String, Goods> tmpGoodsMap = new HashMap<>();
        String select_goods_default_value = null;
        for (BaseConf record : list) {
            String code = record.getCode();

            //基础初始化
            tmpMap.put(code, record);

            //select_goods 封装
            String gFilter = record.getGFilter();
            if (StringUtils.isNotBlank(gFilter) && StringUtils.isNotBlank(SYSTEM_CODE) && gFilter.contains(SYSTEM_CODE)) {
                String gCode = record.getGCode();
                if (StringUtils.isNotBlank(gCode) && SELECT_GOODS_G_CODE.contains(gCode.trim())) {
                    if (SELECT_GOODS_DEFAULT.contains(code.trim())) {
                        select_goods_default_value = record.getValue();
                    } else {
                        Goods goods = new Goods();
                        goods.setGoodsXpathById(code);
                        goods.setGoodsContainNames(Arrays.asList(record.getValue().split(",")));
                        tmpGoodsMap.put(code, goods);
                    }
                }
            }
        }

        //默认项
        log.info("SYSTEM_CODE={},select_goods_default={}", SYSTEM_CODE, select_goods_default_value);
        Goods goods = tmpGoodsMap.get(select_goods_default_value);
        if (goods != null) {
            String s = JSON.toJSONString(goods);
            Goods goods1 = JSON.parseObject(s, Goods.class);
            tmpGoodsMap.put(SELECT_GOODS_DEFAULT, goods1);
        }

        if (tmpGoodsMap.size() > 0) {
            goodsMap = tmpGoodsMap;
        }
        log.info("goodsMap={}", JSON.toJSONString(goodsMap));

        if (tmpMap.size() > 0) {
            dictMap = tmpMap;
        }

        return tmpMap;
    }

    @Override
    public Set<String> cleanAllGroovy() {
        Set<String> groovyList = groovyMap.keySet();
        groovyMap.clear();
        return groovyList;
    }

    @Override
    public BaseConf getByCode(String code) {
        return dictMap.get(code);
    }


    /**
     * //这2个参数需要查询数据库
     * String goodsXpathById = "includeIdNative_1";
     * List<String> goodsContainNames = Arrays.asList(new String[]{"Bluetooth", "APP", "RGB"});
     *
     * @param goodsXpathId
     * @return
     */
    @Override
    public Goods getGoodsByXpathId(String goodsXpathId) {
        if (StringUtils.isBlank(goodsXpathId)) {
            goodsXpathId = SELECT_GOODS_DEFAULT;
        }

        Goods goods = goodsMap.get(goodsXpathId);
        if (goods == null) {
            throw new SysConfException("系统配置异常goodsXpathId=" + goodsXpathId);
        } else {
            return goods;
        }
    }

    @Override
    public String getAsin() {
        BaseConf baseConf = dictMap.get(SYSTEM_CODE + "_" + GOODS_ASIN);
        if (baseConf == null) {
            return null;
        }
        return baseConf.getValue();
    }

    @Override
    public String getPromoteNameByAsins(String asin) {
        String value = asin;
        BaseConf baseConf = dictMap.get(asin);
        if (baseConf != null) {
            value = baseConf.getValue();

            if (StringUtils.isBlank(value)) {
                value = asin;
            }
        }
        return value;
    }

    @Override
    public Page pageList(BaseConfPageReq req) {
        PageHelper.startPage(req.getPageNum(), req.getPageSize());
        LambdaQueryWrapper<BaseConf> queryWrapper = new LambdaQueryWrapper();
        if (StringUtils.isNotBlank(req.getCode())) {
            queryWrapper.like(BaseConf::getCode, req.getCode());
        }
        if (StringUtils.isNotBlank(req.getValue())) {
            queryWrapper.like(BaseConf::getValue, req.getValue());
        }
        if (StringUtils.isNotBlank(req.getGCode())) {
            queryWrapper.like(BaseConf::getGCode, req.getGCode());
        }
        if (StringUtils.isNotBlank(req.getGFilter())) {
            queryWrapper.like(BaseConf::getGFilter, req.getGFilter());
        }
        if (StringUtils.isNotBlank(req.getDataType())) {
            queryWrapper.like(BaseConf::getDataType, req.getDataType());
        }
        if (StringUtils.isNotBlank(req.getDescrip())) {
            queryWrapper.like(BaseConf::getDescrip, req.getDescrip());
        }
        queryWrapper.orderByDesc(BaseConf::getId);
        List<BaseConf> list = baseConfMapper.selectList(queryWrapper);
        return new Page<>(list, new PageInfo<>(list).getTotal(), req);
    }

    @Override
    public String getUserCode() {
        return SYSTEM_CODE;
    }

    @Override
    public String[] getDingDingTokenAndSecret() {
        BaseConf baseConf = dictMap.get(SYSTEM_CODE + "_" + DIGNDING_TOKEN_SECRET);
        if (baseConf == null) {
            return null;
        }
        String value = baseConf.getValue();
        if (StringUtils.isBlank(value)) {
            return null;
        }
        String[] split = value.split(",");
        if (split != null && split.length == 2) {
            return split;
        } else {
            return null;
        }
    }

    @Override
    public List<BaseConf> listByGCode(String gCode) {
        if (dictMap != null && dictMap.size() > 0) {
            List<BaseConf> list = dictMap.values().stream().filter(e -> gCode.equals(e.getGCode())).collect(Collectors.toList());
            return list;
        }
        return null;
    }

    @Override
    public String getGroovyByCodeOrId(String code, String id) {
        String reStr = null;

        BaseConf baseConf = null;
        if (StringUtils.isNotBlank(id)) {
            baseConf = baseConfMapper.selectById(id);
        } else if (StringUtils.isNotBlank(code)) {
            QueryWrapper<BaseConf> query = new QueryWrapper<>();
            query.eq("code", code);
            query.eq("status", 1);
            baseConf = baseConfMapper.selectOne(query);
        }

        if (baseConf != null) {
            reStr = baseConf.getValue();
        }
        return reStr;
    }

    @Override
    public Object exeGroovy(String groovy, WebDriver driver) {
        Object re = null;
        if (StringUtils.isBlank(groovy)) {
            return re;
        }

        try {
            GroovyObject groovyObject = groovyMap.get(groovy);
            if (groovyObject == null) {
                groovyObject = GroovyUtil.createGroovyObject(groovy);
                groovyMap.put(groovy, groovyObject);
            }
            re = groovyObject.invokeMethod("parse", driver);
        } catch (Exception e) {
            log.error("groovy执行异常,groovy={}", groovy, e);
            throw new RuntimeException("groovy执行异常,groovy=" + groovy);
        }
        return re;
    }
}
